#!/usr/bin/env python

import sys
import os
try:
     import pygtk
     pygtk.require("2.0")
     import urllib
except:
      pass
try:
    import gtk
    import gtk.glade
    import openbabel
except:
    sys.exit(1)

class OpenBabel_Python:
    def __init__(self):
        # Load Glade file - Note: Must be in working directory.
        self.wTree = gtk.glade.XML("gui.glade") 
        self.dic = { "on_button1_clicked" : self.on_button1_clicked,
                "on_quit1_button_press_event" : gtk.main_quit,
                "on_filechooserbutton1_selection_changed" : self.on_filechooserbutton1_selection_changed,
                "on_filechooserbutton3_selection_changed" : self.on_filechooserbutton3_selection_changed, 
                "on_window1_delete_event" : gtk.main_quit,
                "on_button2_clicked" : self.on_button2_clicked,
                "on_checkbutton2_toggled" : self.on_checkbutton2_toggled,
                "on_checkbutton1_toggled" : self.on_checkbutton1_toggled,
                "on_combobox1_changed" : self.on_combobox1_changed} 
        self.wTree.signal_autoconnect(self.dic)
        self.window = self.wTree.get_widget("window1")
        self.inputpath = self.wTree.get_widget("entry1")
        self.outputtext = self.wTree.get_widget("textview1")
        self.inputype = self.wTree.get_widget("combobox1")
        self.outputype = self.wTree.get_widget("combobox2")
        self.outputpath = self.wTree.get_widget("entry2")
        self.pubchem = self.wTree.get_widget("entry3")
        self.pubchem_enable = self.wTree.get_widget("checkbutton1")
        self.pdb_enable = self.wTree.get_widget("checkbutton2")
        self.pdb = self.wTree.get_widget("entry4")
        self.inputfileselector = self.wTree.get_widget("filechooserbutton1")
        self.outputfileselector = self.wTree.get_widget("filechooserbutton3")
        self.inputbutton = self.wTree.get_widget("button2")
        self.pdb_color = self.wTree.get_widget("checkbutton3")
        self.file = {"alc - Alchemy":"alc",
                     "bgf - MSI BGF":"bgf",
                     "box - Dock 3.5 Box":"box",
                     "bs - Ball and Stick":"bs",
                     "c3d1 - Chem3D Cartesian 1":"c3d1",
                     "c3d2 - Chem3D Cartesian 2":"c3d2",
                     "caccrt - Cacao Cartesian":"caccrt",
                     "cache - CAChe MolStruct":"cache",
                     "cacint - Cacao Internal":"cacint",
                     "car - Accelrys/MSI Biosym/Insight II CAR":"car",
                     "ccc - CCC":"ccc",
                     "cht - Chemtool":"cht",
                     "cml - Chemical Markup Language":"cml",
                     "cmlr - CML React":"cmlr",
                     "com - Gaussian 98/03 Cartesian Input":"com",
                     "copy - Raw Copy":"copy",
                     "crk2d - Chemical Resource Kit 2D":"crk2d",
                     "crk3d - Chemical Resource Kit 3D":"crk3d",
                     "csr - Accelrys/MSI Quanta CSR":"csr",
                     "cssr - CSD CSSR":"cssr",
                     "ct - ChemDraw Connection Table":"ct",
                     "dmol - DMol3 coordinates":"dmol",
                     "ent - Protein Data Bank":"ent",
                     "fasta - FASTA":"fasta",
                     "feat - Feature":"feat",
                     "fh - Fenske-Hall Z-Matrix":"fh",
                     "fix - SMILES FIX":"fix",
                     "fpt - Fingerprint":"fpt",
                     "fract - Free Form Fractional":"fract",
                     "fs - FastSearch":"fs",
                     "g03 - Gaussian98/03 Output":"g03",
                     "g98 - Gaussian98/03 Output":"g98",
                     "gam - GAMESS Output":"gam",
                     "gamin - GAMESS Input":"gamin",
                     "gamout - GAMESS Output":"gamout",
                     "gau - Gaussian 98/03 Cartesian Input":"gau",
                     "gpr - Ghemical":"gpr",
                     "gr96 - GROMOS96":"gr96",
                     "hin - HyperChem HIN":"hin",
                     "inchi - InChI":"inchi",
                     "inp - GAMESS Input":"inp",
                     "ins - ShelX":"ins",
                     "jin - Jaguar input":"jin",
                     "jout - Jaguar output":"jout",
                     "mdl - MDL Molfile":"mdl",
                     "mmd - MacroModel":"mmd",
                     "mmod - MacroModel":"mmod",
                     "mol2 - Sybyl mol2":"mol2",
                     "mol - MDL Molfile":"mol",
                     "mopcrt - MOPAC Cartesian":"mopcrt",
                     "mopout - MOPAC Output":"mopout",
                     "mpd - Sybyl descriptor":"mpd",
                     "mpqc - MPQC output":"mpqc",
                     "mpqcin - MPQC simplified input":"mpqcin",
                     "nw - NWChem input":"nw",
                     "nwo - NWChem output":"nwo",
                     "pc - PubChem":"pc",
                     "pcm - PCModel":"pcm",
                     "pdb - Protein Data Bank":"pdb",
                     "pov - POV-Ray input":"pov",
                     "pqs - Parallel Quantum Solutions":"pqs",
                     "prep - Amber Prep":"prep",
                     "qcin - Q-Chem input":"qcin",
                     "qcout - Q-Chem output":"qcout",
                     "report - Open Babel report":"report",
                     "res - ShelX":"res",
                     "rxn - MDL RXN":"rxn",
                     "sd - MDL Molfile":"sd",
                     "sdf - MDL Molfile":"sdf",
                     "smi - SMILES":"smi",
                     "test - Test":"test",
                     "tmol - TurboMole Coordinate":"tmol",
                     "txyz - Tinker XYZ":"txyz",
                     "unixyz - UniChem XYZ":"unixyx",
                     "vmol - ViewMol":"vmol",
                     "xed - XED":"xed",
                     "xml - XML":"xml",
                     "xyz - XYZ (format)":"xyz",
                     "yob - YASARA Yob":"yob",
                     "zin - Zindo":"zin"}
        self.filter = gtk.FileFilter()
        for v in self.file.itervalues():
            self.filter.add_pattern("*." + v)
            self.filter.add_pattern("*." + v + ".gz")
        self.filter.set_name("All OpenBabel Supported Formats")
        self.inputfileselector.add_filter(self.filter)
        self.filter = gtk.FileFilter()
        self.filter.set_name("All Files")
        self.filter.add_pattern("*")
        self.inputfileselector.add_filter(self.filter)
        self.pixbuf = gtk.gdk.pixbuf_new_from_file("Babel256.png")
        self.window.set_icon(self.pixbuf)
        self.textbuffer = gtk.TextBuffer(table=None)
        self.outputtext.set_buffer(self.textbuffer)
        self.inputbutton.set_sensitive(False)
        self.jmol_allowable_formats = ["cml", "gamin", "gau", "gpr", "jin", "mdl", "mol", "pdb", "sd", "sdf", "xyz"]               
    
    def pubchem_get(self):
        self.pubchem_sdf = urllib.urlopen("http://pubchem.ncbi.nlm.nih.gov/summary/summary.cgi?cid=" + self.pubchem.get_text() + "&disopt=DisplaySDF")
        self.pubchem_string = str(self.pubchem_sdf.read())
        self.pubchem_dwlnd = open("jmol/molecules/" + self.pubchem.get_text() + ".sdf", "w")
        self.pubchem_dwlnd.write(self.pubchem_string)
        self.pubchem_dwlnd.close()
    
    def jmol_app(self):
        if self.pubchem_enable.get_active() == True:
            self.pubchem_get()
            self.fileloc = "jmol/molecules/" + self.pubchem.get_text() + ".sdf"
        elif self.pdb_enable.get_active() == True:
            self.pdb_get()
            self.fileloc = "jmol/molecules/" + self.pdb.get_text() + ".pdb.gz"
        else:
            self.fileloc = self.inputpath.get_text() 
        if self.pdb_color.get_active() == True and self.pdb_enable.get_active() == True:
            os.system("java -jar jmol/Jmol.jar -s pdb_rasmol.script " + self.fileloc)
        else:
            os.system("java -jar jmol/Jmol.jar " + self.fileloc)
    
    def convert(self):
        self.obConversion = openbabel.OBConversion()
        self.inputpathstring = self.inputpath.get_text() 
        self.inputstring = self.inputype.get_active_text()
        self.outputstring = self.outputype.get_active_text()
        try:
            self.outputpathstring = self.parsed_URI + self.outputpath.get_text()
        except AttributeError:
                self.textbuffer.set_text("ERROR: Please Choose a different output folder")
        self.dummy = openbabel.OBMol()
        if self.pubchem_enable.get_active() == True:
            self.pubchem_get()
            self.obConversion.SetInAndOutFormats("sdf", self.file[self.outputstring])
            self.obConversion.ReadFile(self.dummy, "jmol/molecules/" + self.pubchem.get_text() + ".sdf")
            self.pubchem_original_format = "sdf"
        elif self.pdb_enable.get_active() == True:
            self.pdb_get()
            self.obConversion.SetInAndOutFormats("pdb", self.file[self.outputstring])
            self.obConversion.ReadFile(self.dummy, "jmol/molecules/" + self.pdb.get_text() + ".pdb.gz")
            self.pubchem_original_format = "pdb"    
        else:
            self.obConversion.SetInAndOutFormats(self.file[self.inputstring], self.file[self.outputstring])
            self.obConversion.ReadFile(self.dummy, self.inputpathstring)
            self.pubchem_original_format = self.file[self.inputstring]
        self.obConversion.WriteFile(self.dummy, self.outputpathstring)
        self.outText = self.obConversion.WriteString(self.dummy)
        self.textbuffer.set_text(self.outText + "\nYour file has been converted from *." + self.pubchem_original_format + " to *." + self.file[self.outputstring] + " and is located at:\n" + self.outputpathstring)
        
    def on_filechooserbutton3_selection_changed(self, widget):
        self.outputfileURI = self.outputfileselector.get_uri()
        self.parsed_URI = self.outputfileURI.replace("file://", "") + "/"
    
    def on_filechooserbutton1_selection_changed(self, widget):
        self.inputfileURI = self.inputfileselector.get_uri()
        self.parsed_URI2 = self.inputfileURI.replace("file://", "")
        self.inputpath.set_text(self.parsed_URI2)
    
    def on_button1_clicked(self, widget):
        self.convert()
       
    def on_button2_clicked(self, widget):
        self.jmol_app()
        
    def on_checkbutton1_toggled(self, widget):
        if self.pubchem_enable.get_active() == True:
            self.inputbutton.set_sensitive(True)
        elif self.pubchem_enable.get_active() == False:
            self.inputbutton.set_sensitive(False)
        else:
            pass
            
    def on_checkbutton2_toggled(self, widget):
        if self.pdb_enable.get_active() == True:
            self.inputbutton.set_sensitive(True)
        elif self.pdb_enable.get_active() == False:
            self.inputbutton.set_sensitive(False)
        else:
            pass
    
    def on_combobox1_changed(self, widget):   
        if self.file[self.inputype.get_active_text()] in self.jmol_allowable_formats:
            self.inputbutton.set_sensitive(True)
        elif self.file[self.inputype.get_active_text()] not in self.jmol_allowable_formats:
            self.inputbutton.set_sensitive(False)
        else:
            pass
            
    def pdb_get(self):
        self.pdb_pdb = urllib.urlopen("http://www.rcsb.org/pdb/files/" + self.pdb.get_text() + ".pdb.gz")
        self.pdb_string = str(self.pdb_pdb.read())
        self.pubchem_dwlnd = open("jmol/molecules/" + self.pdb.get_text() + ".pdb.gz", "w")
        self.pubchem_dwlnd.write(self.pdb_string)
        self.pubchem_dwlnd.close()
    
    def main(self):
        gtk.main()

if __name__ == "__main__":
    ob = OpenBabel_Python()
    ob.main()
